static GtkRcContext *gtk_rc_context_get (GtkSettings *settings);
-static guint gtk_rc_style_hash (const gchar *name);
-static gboolean gtk_rc_style_equal (const gchar *a,
- const gchar *b);
static guint gtk_rc_styles_hash (const GSList *rc_styles);
static gboolean gtk_rc_styles_equal (const GSList *a,
const GSList *b);
-static GtkRcStyle* gtk_rc_style_find (GtkRcContext *context,
- const gchar *name);
static GSList * gtk_rc_styles_match (GSList *rc_styles,
GSList *sets,
guint path_length,
const gchar *input_name,
gint input_fd,
const gchar *input_string);
-static guint gtk_rc_parse_statement (GtkRcContext *context,
- GScanner *scanner);
-static guint gtk_rc_parse_style (GtkRcContext *context,
- GScanner *scanner);
-static guint gtk_rc_parse_assignment (GScanner *scanner,
- GtkRcStyle *style,
- GtkRcProperty *prop);
-static guint gtk_rc_parse_bg (GScanner *scanner,
- GtkRcStyle *style);
-static guint gtk_rc_parse_fg (GScanner *scanner,
- GtkRcStyle *style);
-static guint gtk_rc_parse_text (GScanner *scanner,
- GtkRcStyle *style);
-static guint gtk_rc_parse_base (GScanner *scanner,
- GtkRcStyle *style);
-static guint gtk_rc_parse_xthickness (GScanner *scanner,
- GtkRcStyle *style);
-static guint gtk_rc_parse_ythickness (GScanner *scanner,
- GtkRcStyle *style);
-static guint gtk_rc_parse_bg_pixmap (GtkRcContext *context,
- GScanner *scanner,
- GtkRcStyle *rc_style);
-static guint gtk_rc_parse_font (GScanner *scanner,
- GtkRcStyle *rc_style);
-static guint gtk_rc_parse_fontset (GScanner *scanner,
- GtkRcStyle *rc_style);
-static guint gtk_rc_parse_font_name (GScanner *scanner,
- GtkRcStyle *rc_style);
-static guint gtk_rc_parse_engine (GtkRcContext *context,
- GScanner *scanner,
- GtkRcStyle **rc_style);
-static guint gtk_rc_parse_pixmap_path (GtkRcContext *context,
- GScanner *scanner);
-static void gtk_rc_parse_pixmap_path_string (GtkRcContext *context,
- GScanner *scanner,
- const gchar *pix_path);
-static guint gtk_rc_parse_module_path (GScanner *scanner);
-static guint gtk_rc_parse_im_module_file (GScanner *scanner);
-static guint gtk_rc_parse_path_pattern (GtkRcContext *context,
- GScanner *scanner);
-static guint gtk_rc_parse_stock (GtkRcContext *context,
- GScanner *scanner,
- GtkRcStyle *rc_style,
- GtkIconFactory *factory);
-static guint gtk_rc_parse_logical_color (GScanner *scanner,
- GtkRcStyle *rc_style,
- GHashTable *hash);
static void gtk_rc_clear_hash_node (gpointer key,
gpointer data,
void
gtk_rc_parse_string (const gchar *rc_string)
{
- GtkRcFile *rc_file;
- GSList *tmp_list;
-
- g_return_if_fail (rc_string != NULL);
-
-#if 0
- rc_file = g_new (GtkRcFile, 1);
- rc_file->is_string = TRUE;
- rc_file->name = g_strdup (rc_string);
- rc_file->canonical_name = NULL;
- rc_file->directory = NULL;
- rc_file->mtime = 0;
- rc_file->reload = TRUE;
-
- global_rc_files = g_slist_append (global_rc_files, rc_file);
-
- for (tmp_list = rc_contexts; tmp_list; tmp_list = tmp_list->next)
- gtk_rc_context_parse_string (tmp_list->data, rc_string);
-#endif
}
static GtkRcFile *
void
gtk_rc_parse (const gchar *filename)
{
- GSList *tmp_list;
-
- g_return_if_fail (filename != NULL);
-
-#if 0
- add_to_rc_file_list (&global_rc_files, filename, TRUE);
-
- for (tmp_list = rc_contexts; tmp_list; tmp_list = tmp_list->next)
- gtk_rc_context_parse_file (tmp_list->data, filename, GTK_PATH_PRIO_RC, TRUE);
-#endif
}
/* Handling of RC styles */
gint input_fd,
const gchar *input_string)
{
- GScanner *scanner;
- guint i;
- gboolean done;
-
-#if 0
- scanner = gtk_rc_scanner_new ();
-
- if (input_fd >= 0)
- {
- g_assert (input_string == NULL);
-
- g_scanner_input_file (scanner, input_fd);
- }
- else
- {
- g_assert (input_string != NULL);
-
- g_scanner_input_text (scanner, input_string, strlen (input_string));
- }
- scanner->input_name = input_name;
-
- for (i = 0; i < G_N_ELEMENTS (symbols); i++)
- g_scanner_scope_add_symbol (scanner, 0, symbol_names + symbols[i].name_offset, GINT_TO_POINTER (symbols[i].token));
- done = FALSE;
- while (!done)
- {
- if (g_scanner_peek_next_token (scanner) == G_TOKEN_EOF)
- done = TRUE;
- else
- {
- guint expected_token;
-
- expected_token = gtk_rc_parse_statement (context, scanner);
-
- if (expected_token != G_TOKEN_NONE)
- {
- const gchar *symbol_name = NULL;
- gchar *msg = NULL;
-
- if (scanner->scope_id == 0)
- {
- guint token;
-
- /* if we are in scope 0, we know the symbol names
- * that are associated with certain token values.
- * so we look them up to make the error messages
- * more readable.
- */
- if (expected_token > GTK_RC_TOKEN_INVALID &&
- expected_token < GTK_RC_TOKEN_LAST)
- {
- const gchar *sym = NULL;
-
- for (i = 0; i < G_N_ELEMENTS (symbols); i++)
- if (symbols[i].token == expected_token)
- sym = symbol_names + symbols[i].name_offset;
-
- if (sym)
- msg = g_strconcat ("e.g. `", sym, "'", NULL);
- }
-
- token = scanner->token;
- if (token > GTK_RC_TOKEN_INVALID &&
- token < GTK_RC_TOKEN_LAST)
- {
- symbol_name = "???";
- for (i = 0; i < G_N_ELEMENTS (symbols); i++)
- if (symbols[i].token == scanner->token)
- symbol_name = symbol_names + symbols[i].name_offset;
- }
- }
-
- g_scanner_unexp_token (scanner,
- expected_token,
- NULL,
- "keyword",
- symbol_name,
- msg,
- TRUE);
- g_free (msg);
- done = TRUE;
- }
- }
- }
-
- g_scanner_destroy (scanner);
-#endif
}
static guint
return (a == b);
}
-static guint
-gtk_rc_style_hash (const gchar *name)
-{
- guint result;
-
- result = 0;
- while (*name)
- result += (result << 3) + *name++;
-
- return result;
-}
-
-static gboolean
-gtk_rc_style_equal (const gchar *a,
- const gchar *b)
-{
- return (strcmp (a, b) == 0);
-}
-
-static GtkRcStyle*
-gtk_rc_style_find (GtkRcContext *context,
- const gchar *name)
-{
- if (context->rc_style_ht)
- return g_hash_table_lookup (context->rc_style_ht, (gpointer) name);
- else
- return NULL;
-}
-
static GtkStyle *
gtk_rc_style_to_style (GtkRcContext *context,
GtkRcStyle *rc_style)
return FALSE;
}
-static guint
-rc_parse_token_or_compound (GScanner *scanner,
- GtkRcStyle *style,
- GString *gstring,
- GTokenType delimiter)
+const GtkRcProperty*
+_gtk_rc_style_lookup_rc_property (GtkRcStyle *rc_style,
+ GQuark type_name,
+ GQuark property_name)
{
- guint token = g_scanner_get_next_token (scanner);
+ GtkRcProperty *node = NULL;
- /* we either scan a single token (skipping comments)
- * or a compund statement.
- * compunds are enclosed in (), [] or {} braces, we read
- * them in via deep recursion.
- */
+ g_return_val_if_fail (GTK_IS_RC_STYLE (rc_style), NULL);
- switch (token)
+ if (rc_style->rc_properties)
{
- gchar *string;
- case G_TOKEN_INT:
- g_string_append_printf (gstring, " 0x%lx", scanner->value.v_int);
- break;
- case G_TOKEN_FLOAT:
- g_string_append_printf (gstring, " %f", scanner->value.v_float);
- break;
- case G_TOKEN_STRING:
- string = g_strescape (scanner->value.v_string, NULL);
- g_string_append (gstring, " \"");
- g_string_append (gstring, string);
- g_string_append_c (gstring, '"');
- g_free (string);
- break;
- case G_TOKEN_IDENTIFIER:
- g_string_append_c (gstring, ' ');
- g_string_append (gstring, scanner->value.v_identifier);
- break;
- case G_TOKEN_COMMENT_SINGLE:
- case G_TOKEN_COMMENT_MULTI:
- return rc_parse_token_or_compound (scanner, style, gstring, delimiter);
- case G_TOKEN_LEFT_PAREN:
- g_string_append_c (gstring, ' ');
- g_string_append_c (gstring, token);
- token = rc_parse_token_or_compound (scanner, style, gstring, G_TOKEN_RIGHT_PAREN);
- if (token != G_TOKEN_NONE)
- return token;
- break;
- case G_TOKEN_LEFT_CURLY:
- g_string_append_c (gstring, ' ');
- g_string_append_c (gstring, token);
- token = rc_parse_token_or_compound (scanner, style, gstring, G_TOKEN_RIGHT_CURLY);
- if (token != G_TOKEN_NONE)
- return token;
- break;
- case G_TOKEN_LEFT_BRACE:
- g_string_append_c (gstring, ' ');
- g_string_append_c (gstring, token);
- token = rc_parse_token_or_compound (scanner, style, gstring, G_TOKEN_RIGHT_BRACE);
- if (token != G_TOKEN_NONE)
- return token;
- break;
- case '@':
- if (g_scanner_peek_next_token (scanner) == G_TOKEN_IDENTIFIER)
- {
- GdkColor color;
- gchar rbuf[G_ASCII_DTOSTR_BUF_SIZE];
- gchar gbuf[G_ASCII_DTOSTR_BUF_SIZE];
- gchar bbuf[G_ASCII_DTOSTR_BUF_SIZE];
-
- g_scanner_get_next_token (scanner);
-
- if (!style || !lookup_color (style, scanner->value.v_identifier,
- &color))
- {
- g_scanner_warn (scanner, "Invalid symbolic color '%s'",
- scanner->value.v_identifier);
- return G_TOKEN_IDENTIFIER;
- }
+ GtkRcProperty key;
+ key.type_name = type_name;
+ key.property_name = property_name;
- g_string_append_printf (gstring, " { %s, %s, %s }",
- g_ascii_formatd (rbuf, sizeof (rbuf),
- "%0.4f",
- color.red / 65535.0),
- g_ascii_formatd (gbuf, sizeof (gbuf),
- "%0.4f",
- color.green / 65535.0),
- g_ascii_formatd (bbuf, sizeof (bbuf),
- "%0.4f",
- color.blue / 65535.0));
- break;
- }
- else
- return G_TOKEN_IDENTIFIER;
- default:
- if (token >= 256 || token < 1)
- return delimiter ? delimiter : G_TOKEN_STRING;
- g_string_append_c (gstring, ' ');
- g_string_append_c (gstring, token);
- if (token == delimiter)
- return G_TOKEN_NONE;
- break;
+ node = bsearch (&key,
+ rc_style->rc_properties->data, rc_style->rc_properties->len,
+ sizeof (GtkRcProperty), gtk_rc_properties_cmp);
}
- if (!delimiter)
- return G_TOKEN_NONE;
- else
- return rc_parse_token_or_compound (scanner, style, gstring, delimiter);
+
+ return node;
}
-static guint
-gtk_rc_parse_assignment (GScanner *scanner,
- GtkRcStyle *style,
- GtkRcProperty *prop)
+static gchar*
+gtk_rc_check_pixmap_dir (const gchar *dir,
+ const gchar *pixmap_file)
{
-#define MY_SCAN_IDENTIFIER TRUE
-#define MY_SCAN_SYMBOLS FALSE
-#define MY_IDENTIFIER_2_STRING FALSE
-#define MY_CHAR_2_TOKEN TRUE
-#define MY_SCAN_IDENTIFIER_NULL FALSE
-#define MY_NUMBERS_2_INT TRUE
-
- gboolean scan_identifier = scanner->config->scan_identifier;
- gboolean scan_symbols = scanner->config->scan_symbols;
- gboolean identifier_2_string = scanner->config->identifier_2_string;
- gboolean char_2_token = scanner->config->char_2_token;
- gboolean scan_identifier_NULL = scanner->config->scan_identifier_NULL;
- gboolean numbers_2_int = scanner->config->numbers_2_int;
- gboolean negate = FALSE;
- gboolean is_color = FALSE;
- guint token;
-
- /* check that this is an assignment */
- if (g_scanner_get_next_token (scanner) != '=')
- return '=';
-
- /* adjust scanner mode */
- scanner->config->scan_identifier = MY_SCAN_IDENTIFIER;
- scanner->config->scan_symbols = MY_SCAN_SYMBOLS;
- scanner->config->identifier_2_string = MY_IDENTIFIER_2_STRING;
- scanner->config->char_2_token = MY_CHAR_2_TOKEN;
- scanner->config->scan_identifier_NULL = MY_SCAN_IDENTIFIER_NULL;
- scanner->config->numbers_2_int = MY_NUMBERS_2_INT;
-
- /* record location */
- if (g_getenv ("GTK_DEBUG"))
- prop->origin = g_strdup_printf ("%s:%u", scanner->input_name, scanner->line);
- else
- prop->origin = NULL;
+ gchar *buf;
- /* parse optional symbolic color prefix */
- if (g_scanner_peek_next_token (scanner) == '@')
- {
- g_scanner_get_next_token (scanner); /* eat color prefix */
- is_color = TRUE;
- }
+ buf = g_build_filename (dir, pixmap_file, NULL);
- /* parse optional sign */
- if (!is_color && g_scanner_peek_next_token (scanner) == '-')
- {
- g_scanner_get_next_token (scanner); /* eat sign */
- negate = TRUE;
- }
+ if (g_file_test (buf, G_FILE_TEST_EXISTS))
+ return buf;
+
+ g_free (buf);
+
+ return NULL;
+ }
- /* parse one of LONG, DOUBLE and STRING or, if that fails, create an
- * unparsed compund
- */
- token = g_scanner_peek_next_token (scanner);
+/**
+ * gtk_rc_find_pixmap_in_path:
+ * @settings: a #GtkSettings
+ * @scanner: Scanner used to get line number information for the
+ * warning message, or %NULL
+ * @pixmap_file: name of the pixmap file to locate.
+ *
+ * Looks up a file in pixmap path for the specified #GtkSettings.
+ * If the file is not found, it outputs a warning message using
+ * g_warning() and returns %NULL.
+ *
+ * Return value: the filename.
+ **/
+gchar*
+gtk_rc_find_pixmap_in_path (GtkSettings *settings,
+ GScanner *scanner,
+ const gchar *pixmap_file)
+{
+ gint i;
+ gchar *filename;
+ GSList *tmp_list;
- if (is_color && token != G_TOKEN_IDENTIFIER)
+ GtkRcContext *context = gtk_rc_context_get (settings);
+
+ if (context->pixmap_path)
+ for (i = 0; context->pixmap_path[i] != NULL; i++)
+ {
+ filename = gtk_rc_check_pixmap_dir (context->pixmap_path[i], pixmap_file);
+ if (filename)
+ return filename;
+ }
+
+ tmp_list = current_files_stack;
+ while (tmp_list)
{
- token = G_TOKEN_IDENTIFIER;
- goto out;
+ GtkRcFile *curfile = tmp_list->data;
+ filename = gtk_rc_check_pixmap_dir (curfile->directory, pixmap_file);
+ if (filename)
+ return filename;
+
+ tmp_list = tmp_list->next;
}
+
+ if (scanner)
+ g_scanner_warn (scanner,
+ _("Unable to locate image file in pixmap_path: \"%s\""),
+ pixmap_file);
+ else
+ g_warning (_("Unable to locate image file in pixmap_path: \"%s\""),
+ pixmap_file);
+
+ return NULL;
+}
+
+/**
+ * gtk_rc_find_module_in_path:
+ * @module_file: name of a theme engine
+ *
+ * Searches for a theme engine in the GTK+ search path. This function
+ * is not useful for applications and should not be used.
+ *
+ * Return value: The filename, if found (must be freed with g_free()),
+ * otherwise %NULL.
+ **/
+gchar*
+gtk_rc_find_module_in_path (const gchar *module_file)
+{
+ return _gtk_find_module (module_file, "engines");
+}
+
+/**
+ * gtk_rc_parse_state:
+ * @scanner:
+ * @state:
+ *
+ * Deprecated:3.0: Use #GtkCssProvider instead
+ */
+guint
+gtk_rc_parse_state (GScanner *scanner,
+ GtkStateType *state)
+{
+ guint old_scope;
+ guint token;
+ g_return_val_if_fail (scanner != NULL, G_TOKEN_ERROR);
+ g_return_val_if_fail (state != NULL, G_TOKEN_ERROR);
+
+ /* we don't know where we got called from, so we reset the scope here.
+ * if we bail out due to errors, we *don't* reset the scope, so the
+ * error messaging code can make sense of our tokens.
+ */
+ old_scope = g_scanner_set_scope (scanner, 0);
+
+ token = g_scanner_get_next_token (scanner);
+ if (token != G_TOKEN_LEFT_BRACE)
+ return G_TOKEN_LEFT_BRACE;
+
+ token = g_scanner_get_next_token (scanner);
switch (token)
{
- case G_TOKEN_INT:
- g_scanner_get_next_token (scanner);
- g_value_init (&prop->value, G_TYPE_LONG);
- g_value_set_long (&prop->value, negate ? -scanner->value.v_int : scanner->value.v_int);
- token = G_TOKEN_NONE;
+ case GTK_RC_TOKEN_ACTIVE:
+ *state = GTK_STATE_ACTIVE;
break;
- case G_TOKEN_FLOAT:
- g_scanner_get_next_token (scanner);
- g_value_init (&prop->value, G_TYPE_DOUBLE);
- g_value_set_double (&prop->value, negate ? -scanner->value.v_float : scanner->value.v_float);
- token = G_TOKEN_NONE;
+ case GTK_RC_TOKEN_INSENSITIVE:
+ *state = GTK_STATE_INSENSITIVE;
break;
- case G_TOKEN_STRING:
- g_scanner_get_next_token (scanner);
- if (negate)
- token = G_TOKEN_INT;
- else
- {
- g_value_init (&prop->value, G_TYPE_STRING);
- g_value_set_string (&prop->value, scanner->value.v_string);
- token = G_TOKEN_NONE;
- }
+ case GTK_RC_TOKEN_NORMAL:
+ *state = GTK_STATE_NORMAL;
break;
- case G_TOKEN_IDENTIFIER:
- if (is_color)
- {
- GdkColor color;
- gchar rbuf[G_ASCII_DTOSTR_BUF_SIZE];
- gchar gbuf[G_ASCII_DTOSTR_BUF_SIZE];
- gchar bbuf[G_ASCII_DTOSTR_BUF_SIZE];
- GString *gstring;
+ case GTK_RC_TOKEN_PRELIGHT:
+ *state = GTK_STATE_PRELIGHT;
+ break;
+ case GTK_RC_TOKEN_SELECTED:
+ *state = GTK_STATE_SELECTED;
+ break;
+ default:
+ return /* G_TOKEN_SYMBOL */ GTK_RC_TOKEN_NORMAL;
+ }
+
+ token = g_scanner_get_next_token (scanner);
+ if (token != G_TOKEN_RIGHT_BRACE)
+ return G_TOKEN_RIGHT_BRACE;
+
+ g_scanner_set_scope (scanner, old_scope);
- g_scanner_get_next_token (scanner);
+ return G_TOKEN_NONE;
+}
- if (!style || !lookup_color (style, scanner->value.v_identifier,
- &color))
- {
- g_scanner_warn (scanner, "Invalid symbolic color '%s'",
- scanner->value.v_identifier);
- token = G_TOKEN_IDENTIFIER;
- break;
- }
+/**
+ * gtk_rc_parse_priority:
+ * @scanner:
+ * @priority:
+ *
+ * Deprecated:3.0: Use #GtkCssProvider instead
+ */
+guint
+gtk_rc_parse_priority (GScanner *scanner,
+ GtkPathPriorityType *priority)
+{
+ guint old_scope;
+ guint token;
- gstring = g_string_new (NULL);
-
- g_string_append_printf (gstring, " { %s, %s, %s }",
- g_ascii_formatd (rbuf, sizeof (rbuf),
- "%0.4f",
- color.red / 65535.0),
- g_ascii_formatd (gbuf, sizeof (gbuf),
- "%0.4f",
- color.green / 65535.0),
- g_ascii_formatd (bbuf, sizeof (bbuf),
- "%0.4f",
- color.blue / 65535.0));
-
- g_value_init (&prop->value, G_TYPE_GSTRING);
- g_value_take_boxed (&prop->value, gstring);
- token = G_TOKEN_NONE;
- break;
- }
- /* fall through */
- case G_TOKEN_LEFT_PAREN:
- case G_TOKEN_LEFT_CURLY:
- case G_TOKEN_LEFT_BRACE:
- if (!negate)
- {
- GString *gstring = g_string_new (NULL);
- gboolean parse_on = TRUE;
-
- /* allow identifier(foobar) to support color expressions */
- if (token == G_TOKEN_IDENTIFIER)
- {
- g_scanner_get_next_token (scanner);
-
- g_string_append_c (gstring, ' ');
- g_string_append (gstring, scanner->value.v_identifier);
-
- /* temporarily reset scanner mode to default, so we
- * don't peek the next token in a mode that only makes
- * sense in this function; because if anything but
- * G_TOKEN_LEFT_PAREN follows, the next token will be
- * parsed by our caller.
- *
- * FIXME: right fix would be to call g_scanner_unget()
- * but that doesn't exist
- */
- scanner->config->scan_identifier = scan_identifier;
- scanner->config->scan_symbols = scan_symbols;
- scanner->config->identifier_2_string = identifier_2_string;
- scanner->config->char_2_token = char_2_token;
- scanner->config->scan_identifier_NULL = scan_identifier_NULL;
- scanner->config->numbers_2_int = numbers_2_int;
-
- token = g_scanner_peek_next_token (scanner);
-
- /* restore adjusted scanner mode */
- scanner->config->scan_identifier = MY_SCAN_IDENTIFIER;
- scanner->config->scan_symbols = MY_SCAN_SYMBOLS;
- scanner->config->identifier_2_string = MY_IDENTIFIER_2_STRING;
- scanner->config->char_2_token = MY_CHAR_2_TOKEN;
- scanner->config->scan_identifier_NULL = MY_SCAN_IDENTIFIER_NULL;
- scanner->config->numbers_2_int = MY_NUMBERS_2_INT;
-
- if (token != G_TOKEN_LEFT_PAREN)
- {
- token = G_TOKEN_NONE;
- parse_on = FALSE;
- }
- }
-
- if (parse_on)
- token = rc_parse_token_or_compound (scanner, style, gstring, 0);
-
- if (token == G_TOKEN_NONE)
- {
- g_string_append_c (gstring, ' ');
- g_value_init (&prop->value, G_TYPE_GSTRING);
- g_value_take_boxed (&prop->value, gstring);
- }
- else
- g_string_free (gstring, TRUE);
- break;
- }
- /* fall through */
- default:
- g_scanner_get_next_token (scanner);
- token = G_TOKEN_INT;
- break;
- }
-
- out:
-
- /* restore scanner mode */
- scanner->config->scan_identifier = scan_identifier;
- scanner->config->scan_symbols = scan_symbols;
- scanner->config->identifier_2_string = identifier_2_string;
- scanner->config->char_2_token = char_2_token;
- scanner->config->scan_identifier_NULL = scan_identifier_NULL;
- scanner->config->numbers_2_int = numbers_2_int;
-
- return token;
-}
-
-static gboolean
-is_c_identifier (const gchar *string)
-{
- const gchar *p;
- gboolean is_varname;
-
- is_varname = strchr ("_" G_CSET_a_2_z G_CSET_A_2_Z, string[0]) != NULL;
- for (p = string + 1; *p && is_varname; p++)
- is_varname &= strchr (G_CSET_DIGITS "-_" G_CSET_a_2_z G_CSET_A_2_Z, *p) != NULL;
-
- return is_varname;
-}
-
-static void
-parse_include_file (GtkRcContext *context,
- GScanner *scanner,
- const gchar *filename)
-{
- char *to_parse = NULL;
-
- if (g_path_is_absolute (filename))
- {
- /* For abolute paths, we call gtk_rc_context_parse_file unconditionally. We
- * don't print an error in this case.
- */
- to_parse = g_strdup (filename);
- }
- else
- {
- /* if a relative path, we look relative to all the RC files in the
- * include stack. We require the file to be found in this case
- * so we can give meaningful error messages, and because on reparsing
- * non-absolute paths don't make sense.
- */
- GSList *tmp_list = current_files_stack;
- while (tmp_list)
- {
- GtkRcFile *curfile = tmp_list->data;
- gchar *tmpname = g_build_filename (curfile->directory, filename, NULL);
-
- if (g_file_test (tmpname, G_FILE_TEST_EXISTS))
- {
- to_parse = tmpname;
- break;
- }
-
- g_free (tmpname);
-
- tmp_list = tmp_list->next;
- }
- }
-
- if (to_parse)
- {
- gtk_rc_context_parse_file (context, to_parse, context->default_priority, FALSE);
- g_free (to_parse);
- }
- else
- {
- g_scanner_warn (scanner,
- _("Unable to find include file: \"%s\""),
- filename);
- }
-
-}
-
-static guint
-gtk_rc_parse_statement (GtkRcContext *context,
- GScanner *scanner)
-{
- guint token;
-
- token = g_scanner_peek_next_token (scanner);
- switch (token)
- {
- case GTK_RC_TOKEN_INCLUDE:
- token = g_scanner_get_next_token (scanner);
- if (token != GTK_RC_TOKEN_INCLUDE)
- return GTK_RC_TOKEN_INCLUDE;
- token = g_scanner_get_next_token (scanner);
- if (token != G_TOKEN_STRING)
- return G_TOKEN_STRING;
- parse_include_file (context, scanner, scanner->value.v_string);
- return G_TOKEN_NONE;
-
- case GTK_RC_TOKEN_STYLE:
- return gtk_rc_parse_style (context, scanner);
-
- case GTK_RC_TOKEN_BINDING:
- return _gtk_binding_parse_binding (scanner);
-
- case GTK_RC_TOKEN_PIXMAP_PATH:
- return gtk_rc_parse_pixmap_path (context, scanner);
-
- case GTK_RC_TOKEN_WIDGET:
- return gtk_rc_parse_path_pattern (context, scanner);
-
- case GTK_RC_TOKEN_WIDGET_CLASS:
- return gtk_rc_parse_path_pattern (context, scanner);
-
- case GTK_RC_TOKEN_CLASS:
- return gtk_rc_parse_path_pattern (context, scanner);
-
- case GTK_RC_TOKEN_MODULE_PATH:
- return gtk_rc_parse_module_path (scanner);
-
- case GTK_RC_TOKEN_IM_MODULE_FILE:
- return gtk_rc_parse_im_module_file (scanner);
-
- case G_TOKEN_IDENTIFIER:
- if (is_c_identifier (scanner->next_value.v_identifier))
- {
- GtkRcProperty prop = { 0, 0, NULL, { 0, }, };
- gchar *name;
-
- g_scanner_get_next_token (scanner); /* eat identifier */
- name = g_strdup (scanner->value.v_identifier);
-
- token = gtk_rc_parse_assignment (scanner, NULL, &prop);
- if (token == G_TOKEN_NONE)
- {
- GtkSettingsValue svalue;
-
- svalue.origin = prop.origin;
- memcpy (&svalue.value, &prop.value, sizeof (prop.value));
- g_strcanon (name, G_CSET_DIGITS "-" G_CSET_a_2_z G_CSET_A_2_Z, '-');
- _gtk_settings_set_property_value_from_rc (context->settings,
- name,
- &svalue);
- }
- g_free (prop.origin);
- if (G_VALUE_TYPE (&prop.value))
- g_value_unset (&prop.value);
- g_free (name);
-
- return token;
- }
- else
- {
- g_scanner_get_next_token (scanner);
- return G_TOKEN_IDENTIFIER;
- }
- default:
- g_scanner_get_next_token (scanner);
- return /* G_TOKEN_SYMBOL */ GTK_RC_TOKEN_STYLE;
- }
-}
-
-static void
-fixup_rc_set (GSList *list,
- GtkRcStyle *orig,
- GtkRcStyle *new)
-{
- while (list)
- {
- GtkRcSet *set = list->data;
- if (set->rc_style == orig)
- set->rc_style = new;
- list = list->next;
- }
-}
-
-static void
-fixup_rc_sets (GtkRcContext *context,
- GtkRcStyle *orig,
- GtkRcStyle *new)
-{
- fixup_rc_set (context->rc_sets_widget, orig, new);
- fixup_rc_set (context->rc_sets_widget_class, orig, new);
- fixup_rc_set (context->rc_sets_class, orig, new);
-}
-
-static guint
-gtk_rc_parse_style (GtkRcContext *context,
- GScanner *scanner)
-{
- GtkRcStyle *rc_style;
- GtkRcStyle *orig_style;
- GtkRcStyle *parent_style = NULL;
- GtkRcStylePrivate *rc_priv = NULL;
- guint token;
- gint i;
- GtkIconFactory *our_factory = NULL;
- GHashTable *our_hash = NULL;
-
- token = g_scanner_get_next_token (scanner);
- if (token != GTK_RC_TOKEN_STYLE)
- return GTK_RC_TOKEN_STYLE;
-
- token = g_scanner_get_next_token (scanner);
- if (token != G_TOKEN_STRING)
- return G_TOKEN_STRING;
-
- rc_style = gtk_rc_style_find (context, scanner->value.v_string);
- if (rc_style)
- orig_style = g_object_ref (rc_style);
- else
- orig_style = NULL;
-
- if (!rc_style)
- {
- rc_style = gtk_rc_style_new ();
- rc_style->name = g_strdup (scanner->value.v_string);
-
- for (i = 0; i < 5; i++)
- rc_style->bg_pixmap_name[i] = NULL;
-
- for (i = 0; i < 5; i++)
- rc_style->color_flags[i] = 0;
- }
-
- rc_priv = GTK_RC_STYLE_GET_PRIVATE (rc_style);
-
- /* If there's a list, its first member is always the factory belonging
- * to this RcStyle
- */
- if (rc_style->icon_factories)
- our_factory = rc_style->icon_factories->data;
- if (rc_priv->color_hashes)
- our_hash = rc_priv->color_hashes->data;
-
- token = g_scanner_peek_next_token (scanner);
- if (token == G_TOKEN_EQUAL_SIGN)
- {
- token = g_scanner_get_next_token (scanner);
-
- token = g_scanner_get_next_token (scanner);
- if (token != G_TOKEN_STRING)
- {
- token = G_TOKEN_STRING;
- goto err;
- }
-
- parent_style = gtk_rc_style_find (context, scanner->value.v_string);
- if (parent_style)
- {
- for (i = 0; i < 5; i++)
- {
- rc_style->color_flags[i] = parent_style->color_flags[i];
- rc_style->fg[i] = parent_style->fg[i];
- rc_style->bg[i] = parent_style->bg[i];
- rc_style->text[i] = parent_style->text[i];
- rc_style->base[i] = parent_style->base[i];
- }
-
- rc_style->xthickness = parent_style->xthickness;
- rc_style->ythickness = parent_style->ythickness;
-
- if (parent_style->font_desc)
- {
- if (rc_style->font_desc)
- pango_font_description_free (rc_style->font_desc);
- rc_style->font_desc = pango_font_description_copy (parent_style->font_desc);
- }
-
- if (parent_style->rc_properties)
- {
- guint i;
-
- for (i = 0; i < parent_style->rc_properties->len; i++)
- insert_rc_property (rc_style,
- &g_array_index (parent_style->rc_properties, GtkRcProperty, i),
- TRUE);
- }
-
- for (i = 0; i < 5; i++)
- {
- g_free (rc_style->bg_pixmap_name[i]);
- rc_style->bg_pixmap_name[i] = g_strdup (parent_style->bg_pixmap_name[i]);
- }
- }
- }
-
- /* get icon_factories and color_hashes from the parent style;
- * if the parent_style doesn't have color_hashes, initializes
- * the color_hashes with the settings' color scheme (if it exists)
- */
- gtk_rc_style_copy_icons_and_colors (rc_style, parent_style, context);
-
- if (rc_style->icon_factories)
- our_factory = rc_style->icon_factories->data;
- if (rc_priv->color_hashes)
- our_hash = rc_priv->color_hashes->data;
-
- token = g_scanner_get_next_token (scanner);
- if (token != G_TOKEN_LEFT_CURLY)
- {
- token = G_TOKEN_LEFT_CURLY;
- goto err;
- }
-
- token = g_scanner_peek_next_token (scanner);
- while (token != G_TOKEN_RIGHT_CURLY)
- {
- switch (token)
- {
- case GTK_RC_TOKEN_BG:
- token = gtk_rc_parse_bg (scanner, rc_style);
- break;
- case GTK_RC_TOKEN_FG:
- token = gtk_rc_parse_fg (scanner, rc_style);
- break;
- case GTK_RC_TOKEN_TEXT:
- token = gtk_rc_parse_text (scanner, rc_style);
- break;
- case GTK_RC_TOKEN_BASE:
- token = gtk_rc_parse_base (scanner, rc_style);
- break;
- case GTK_RC_TOKEN_XTHICKNESS:
- token = gtk_rc_parse_xthickness (scanner, rc_style);
- break;
- case GTK_RC_TOKEN_YTHICKNESS:
- token = gtk_rc_parse_ythickness (scanner, rc_style);
- break;
- case GTK_RC_TOKEN_BG_PIXMAP:
- token = gtk_rc_parse_bg_pixmap (context, scanner, rc_style);
- break;
- case GTK_RC_TOKEN_FONT:
- token = gtk_rc_parse_font (scanner, rc_style);
- break;
- case GTK_RC_TOKEN_FONTSET:
- token = gtk_rc_parse_fontset (scanner, rc_style);
- break;
- case GTK_RC_TOKEN_FONT_NAME:
- token = gtk_rc_parse_font_name (scanner, rc_style);
- break;
- case GTK_RC_TOKEN_ENGINE:
- token = gtk_rc_parse_engine (context, scanner, &rc_style);
- break;
- case GTK_RC_TOKEN_STOCK:
- if (our_factory == NULL)
- gtk_rc_style_prepend_empty_icon_factory (rc_style);
- our_factory = rc_style->icon_factories->data;
- token = gtk_rc_parse_stock (context, scanner, rc_style, our_factory);
- break;
- case GTK_RC_TOKEN_COLOR:
- if (our_hash == NULL)
- {
- gtk_rc_style_prepend_empty_color_hash (rc_style);
- our_hash = rc_priv->color_hashes->data;
- }
- token = gtk_rc_parse_logical_color (scanner, rc_style, our_hash);
- break;
- case G_TOKEN_IDENTIFIER:
- if (is_c_identifier (scanner->next_value.v_identifier))
- {
- GtkRcProperty prop = { 0, 0, NULL, { 0, }, };
- gchar *name;
-
- g_scanner_get_next_token (scanner); /* eat type name */
- prop.type_name = g_quark_from_string (scanner->value.v_identifier);
- if (g_scanner_get_next_token (scanner) != ':' ||
- g_scanner_get_next_token (scanner) != ':')
- {
- token = ':';
- break;
- }
- if (g_scanner_get_next_token (scanner) != G_TOKEN_IDENTIFIER ||
- !is_c_identifier (scanner->value.v_identifier))
- {
- token = G_TOKEN_IDENTIFIER;
- break;
- }
-
- /* it's important that we do the same canonification as GParamSpecPool here */
- name = g_strdup (scanner->value.v_identifier);
- g_strcanon (name, G_CSET_DIGITS "-" G_CSET_a_2_z G_CSET_A_2_Z, '-');
- prop.property_name = g_quark_from_string (name);
- g_free (name);
-
- token = gtk_rc_parse_assignment (scanner, rc_style, &prop);
- if (token == G_TOKEN_NONE)
- {
- g_return_val_if_fail (G_VALUE_TYPE (&prop.value) != 0, G_TOKEN_ERROR);
- insert_rc_property (rc_style, &prop, TRUE);
- }
-
- g_free (prop.origin);
- if (G_VALUE_TYPE (&prop.value))
- g_value_unset (&prop.value);
- }
- else
- {
- g_scanner_get_next_token (scanner);
- token = G_TOKEN_IDENTIFIER;
- }
- break;
- default:
- g_scanner_get_next_token (scanner);
- token = G_TOKEN_RIGHT_CURLY;
- break;
- }
-
- if (token != G_TOKEN_NONE)
- goto err;
-
- token = g_scanner_peek_next_token (scanner);
- } /* while (token != G_TOKEN_RIGHT_CURLY) */
-
- token = g_scanner_get_next_token (scanner);
- if (token != G_TOKEN_RIGHT_CURLY)
- {
- token = G_TOKEN_RIGHT_CURLY;
- goto err;
- }
-
- if (rc_style != orig_style)
- {
- if (!context->rc_style_ht)
- context->rc_style_ht = g_hash_table_new ((GHashFunc) gtk_rc_style_hash,
- (GEqualFunc) gtk_rc_style_equal);
-
- g_hash_table_replace (context->rc_style_ht, rc_style->name, rc_style);
-
- /* If we copied the data into a new rc style, fix up references to the old rc style
- * in bindings that we have.
- */
- if (orig_style)
- fixup_rc_sets (context, orig_style, rc_style);
- }
-
- if (orig_style)
- g_object_unref (orig_style);
-
- return G_TOKEN_NONE;
-
- err:
- if (rc_style != orig_style)
- g_object_unref (rc_style);
-
- if (orig_style)
- g_object_unref (orig_style);
-
- return token;
-}
-
-const GtkRcProperty*
-_gtk_rc_style_lookup_rc_property (GtkRcStyle *rc_style,
- GQuark type_name,
- GQuark property_name)
-{
- GtkRcProperty *node = NULL;
-
- g_return_val_if_fail (GTK_IS_RC_STYLE (rc_style), NULL);
-
- if (rc_style->rc_properties)
- {
- GtkRcProperty key;
-
- key.type_name = type_name;
- key.property_name = property_name;
-
- node = bsearch (&key,
- rc_style->rc_properties->data, rc_style->rc_properties->len,
- sizeof (GtkRcProperty), gtk_rc_properties_cmp);
- }
-
- return node;
-}
-
-static guint
-gtk_rc_parse_bg (GScanner *scanner,
- GtkRcStyle *style)
-{
- GtkStateType state;
- guint token;
-
- token = g_scanner_get_next_token (scanner);
- if (token != GTK_RC_TOKEN_BG)
- return GTK_RC_TOKEN_BG;
-
- token = gtk_rc_parse_state (scanner, &state);
- if (token != G_TOKEN_NONE)
- return token;
-
- token = g_scanner_get_next_token (scanner);
- if (token != G_TOKEN_EQUAL_SIGN)
- return G_TOKEN_EQUAL_SIGN;
-
- style->color_flags[state] |= GTK_RC_BG;
- return gtk_rc_parse_color_full (scanner, style, &style->bg[state]);
-}
-
-static guint
-gtk_rc_parse_fg (GScanner *scanner,
- GtkRcStyle *style)
-{
- GtkStateType state;
- guint token;
-
- token = g_scanner_get_next_token (scanner);
- if (token != GTK_RC_TOKEN_FG)
- return GTK_RC_TOKEN_FG;
-
- token = gtk_rc_parse_state (scanner, &state);
- if (token != G_TOKEN_NONE)
- return token;
-
- token = g_scanner_get_next_token (scanner);
- if (token != G_TOKEN_EQUAL_SIGN)
- return G_TOKEN_EQUAL_SIGN;
-
- style->color_flags[state] |= GTK_RC_FG;
- return gtk_rc_parse_color_full (scanner, style, &style->fg[state]);
-}
-
-static guint
-gtk_rc_parse_text (GScanner *scanner,
- GtkRcStyle *style)
-{
- GtkStateType state;
- guint token;
-
- token = g_scanner_get_next_token (scanner);
- if (token != GTK_RC_TOKEN_TEXT)
- return GTK_RC_TOKEN_TEXT;
-
- token = gtk_rc_parse_state (scanner, &state);
- if (token != G_TOKEN_NONE)
- return token;
-
- token = g_scanner_get_next_token (scanner);
- if (token != G_TOKEN_EQUAL_SIGN)
- return G_TOKEN_EQUAL_SIGN;
-
- style->color_flags[state] |= GTK_RC_TEXT;
- return gtk_rc_parse_color_full (scanner, style, &style->text[state]);
-}
-
-static guint
-gtk_rc_parse_base (GScanner *scanner,
- GtkRcStyle *style)
-{
- GtkStateType state;
- guint token;
-
- token = g_scanner_get_next_token (scanner);
- if (token != GTK_RC_TOKEN_BASE)
- return GTK_RC_TOKEN_BASE;
-
- token = gtk_rc_parse_state (scanner, &state);
- if (token != G_TOKEN_NONE)
- return token;
-
- token = g_scanner_get_next_token (scanner);
- if (token != G_TOKEN_EQUAL_SIGN)
- return G_TOKEN_EQUAL_SIGN;
-
- style->color_flags[state] |= GTK_RC_BASE;
- return gtk_rc_parse_color_full (scanner, style, &style->base[state]);
-}
-
-static guint
-gtk_rc_parse_xthickness (GScanner *scanner,
- GtkRcStyle *style)
-{
- guint token;
-
- token = g_scanner_get_next_token (scanner);
- if (token != GTK_RC_TOKEN_XTHICKNESS)
- return GTK_RC_TOKEN_XTHICKNESS;
-
- if (g_scanner_get_next_token (scanner) != G_TOKEN_EQUAL_SIGN)
- return G_TOKEN_EQUAL_SIGN;
-
- if (g_scanner_get_next_token (scanner) != G_TOKEN_INT)
- return G_TOKEN_INT;
-
- style->xthickness = scanner->value.v_int;
-
- return G_TOKEN_NONE;
-}
-
-static guint
-gtk_rc_parse_ythickness (GScanner *scanner,
- GtkRcStyle *style)
-{
- guint token;
-
- token = g_scanner_get_next_token (scanner);
- if (token != GTK_RC_TOKEN_YTHICKNESS)
- return GTK_RC_TOKEN_YTHICKNESS;
-
- if (g_scanner_get_next_token (scanner) != G_TOKEN_EQUAL_SIGN)
- return G_TOKEN_EQUAL_SIGN;
-
- if (g_scanner_get_next_token (scanner) != G_TOKEN_INT)
- return G_TOKEN_INT;
-
- style->ythickness = scanner->value.v_int;
-
- return G_TOKEN_NONE;
-}
-
-static guint
-gtk_rc_parse_bg_pixmap (GtkRcContext *context,
- GScanner *scanner,
- GtkRcStyle *rc_style)
-{
- GtkStateType state;
- guint token;
- gchar *pixmap_file;
-
- token = g_scanner_get_next_token (scanner);
- if (token != GTK_RC_TOKEN_BG_PIXMAP)
- return GTK_RC_TOKEN_BG_PIXMAP;
-
- token = gtk_rc_parse_state (scanner, &state);
- if (token != G_TOKEN_NONE)
- return token;
-
- token = g_scanner_get_next_token (scanner);
- if (token != G_TOKEN_EQUAL_SIGN)
- return G_TOKEN_EQUAL_SIGN;
-
- token = g_scanner_get_next_token (scanner);
- if (token != G_TOKEN_STRING)
- return G_TOKEN_STRING;
-
- if ((strcmp (scanner->value.v_string, "<parent>") == 0) ||
- (strcmp (scanner->value.v_string, "<none>") == 0))
- pixmap_file = g_strdup (scanner->value.v_string);
- else
- pixmap_file = gtk_rc_find_pixmap_in_path (context->settings,
- scanner, scanner->value.v_string);
-
- if (pixmap_file)
- {
- g_free (rc_style->bg_pixmap_name[state]);
- rc_style->bg_pixmap_name[state] = pixmap_file;
- }
-
- return G_TOKEN_NONE;
-}
-
-static gchar*
-gtk_rc_check_pixmap_dir (const gchar *dir,
- const gchar *pixmap_file)
-{
- gchar *buf;
-
- buf = g_build_filename (dir, pixmap_file, NULL);
-
- if (g_file_test (buf, G_FILE_TEST_EXISTS))
- return buf;
-
- g_free (buf);
-
- return NULL;
- }
-
-/**
- * gtk_rc_find_pixmap_in_path:
- * @settings: a #GtkSettings
- * @scanner: Scanner used to get line number information for the
- * warning message, or %NULL
- * @pixmap_file: name of the pixmap file to locate.
- *
- * Looks up a file in pixmap path for the specified #GtkSettings.
- * If the file is not found, it outputs a warning message using
- * g_warning() and returns %NULL.
- *
- * Return value: the filename.
- **/
-gchar*
-gtk_rc_find_pixmap_in_path (GtkSettings *settings,
- GScanner *scanner,
- const gchar *pixmap_file)
-{
- gint i;
- gchar *filename;
- GSList *tmp_list;
-
- GtkRcContext *context = gtk_rc_context_get (settings);
-
- if (context->pixmap_path)
- for (i = 0; context->pixmap_path[i] != NULL; i++)
- {
- filename = gtk_rc_check_pixmap_dir (context->pixmap_path[i], pixmap_file);
- if (filename)
- return filename;
- }
-
- tmp_list = current_files_stack;
- while (tmp_list)
- {
- GtkRcFile *curfile = tmp_list->data;
- filename = gtk_rc_check_pixmap_dir (curfile->directory, pixmap_file);
- if (filename)
- return filename;
-
- tmp_list = tmp_list->next;
- }
-
- if (scanner)
- g_scanner_warn (scanner,
- _("Unable to locate image file in pixmap_path: \"%s\""),
- pixmap_file);
- else
- g_warning (_("Unable to locate image file in pixmap_path: \"%s\""),
- pixmap_file);
-
- return NULL;
-}
-
-/**
- * gtk_rc_find_module_in_path:
- * @module_file: name of a theme engine
- *
- * Searches for a theme engine in the GTK+ search path. This function
- * is not useful for applications and should not be used.
- *
- * Return value: The filename, if found (must be freed with g_free()),
- * otherwise %NULL.
- **/
-gchar*
-gtk_rc_find_module_in_path (const gchar *module_file)
-{
- return _gtk_find_module (module_file, "engines");
-}
-
-static guint
-gtk_rc_parse_font (GScanner *scanner,
- GtkRcStyle *rc_style)
-{
- guint token;
-
- token = g_scanner_get_next_token (scanner);
- if (token != GTK_RC_TOKEN_FONT)
- return GTK_RC_TOKEN_FONT;
-
- token = g_scanner_get_next_token (scanner);
- if (token != G_TOKEN_EQUAL_SIGN)
- return G_TOKEN_EQUAL_SIGN;
-
- token = g_scanner_get_next_token (scanner);
- if (token != G_TOKEN_STRING)
- return G_TOKEN_STRING;
-
- /* Ignore, do nothing */
-
- return G_TOKEN_NONE;
-}
-
-static guint
-gtk_rc_parse_fontset (GScanner *scanner,
- GtkRcStyle *rc_style)
-{
- guint token;
-
- token = g_scanner_get_next_token (scanner);
- if (token != GTK_RC_TOKEN_FONTSET)
- return GTK_RC_TOKEN_FONTSET;
-
- token = g_scanner_get_next_token (scanner);
- if (token != G_TOKEN_EQUAL_SIGN)
- return G_TOKEN_EQUAL_SIGN;
-
- token = g_scanner_get_next_token (scanner);
- if (token != G_TOKEN_STRING)
- return G_TOKEN_STRING;
-
- /* Do nothing - silently ignore */
-
- return G_TOKEN_NONE;
-}
-
-static guint
-gtk_rc_parse_font_name (GScanner *scanner,
- GtkRcStyle *rc_style)
-{
- guint token;
-
- token = g_scanner_get_next_token (scanner);
- if (token != GTK_RC_TOKEN_FONT_NAME)
- return GTK_RC_TOKEN_FONT;
-
- token = g_scanner_get_next_token (scanner);
- if (token != G_TOKEN_EQUAL_SIGN)
- return G_TOKEN_EQUAL_SIGN;
-
- token = g_scanner_get_next_token (scanner);
- if (token != G_TOKEN_STRING)
- return G_TOKEN_STRING;
-
- if (rc_style->font_desc)
- pango_font_description_free (rc_style->font_desc);
-
- rc_style->font_desc =
- pango_font_description_from_string (scanner->value.v_string);
-
- return G_TOKEN_NONE;
-}
-
-static guint
-gtk_rc_parse_engine (GtkRcContext *context,
- GScanner *scanner,
- GtkRcStyle **rc_style)
-{
- guint token;
- GtkThemeEngine *engine;
- guint result = G_TOKEN_NONE;
- GtkRcStyle *new_style = NULL;
- gboolean parsed_curlies = FALSE;
- GtkRcStylePrivate *rc_priv, *new_priv;
-
- token = g_scanner_get_next_token (scanner);
- if (token != GTK_RC_TOKEN_ENGINE)
- return GTK_RC_TOKEN_ENGINE;
-
- token = g_scanner_get_next_token (scanner);
- if (token != G_TOKEN_STRING)
- return G_TOKEN_STRING;
-
- if (!scanner->value.v_string[0])
- {
- /* Support engine "" {} to mean override to the default engine
- */
- token = g_scanner_get_next_token (scanner);
- if (token != G_TOKEN_LEFT_CURLY)
- return G_TOKEN_LEFT_CURLY;
-
- token = g_scanner_get_next_token (scanner);
- if (token != G_TOKEN_RIGHT_CURLY)
- return G_TOKEN_RIGHT_CURLY;
-
- parsed_curlies = TRUE;
-
- rc_priv = GTK_RC_STYLE_GET_PRIVATE (*rc_style);
-
- if (G_OBJECT_TYPE (*rc_style) != GTK_TYPE_RC_STYLE)
- {
- new_style = gtk_rc_style_new ();
- gtk_rc_style_real_merge (new_style, *rc_style);
-
- new_style->name = g_strdup ((*rc_style)->name);
-
- /* take over icon factories and color hashes
- * from the to-be-deleted style
- */
- new_style->icon_factories = (*rc_style)->icon_factories;
- (*rc_style)->icon_factories = NULL;
- new_priv = GTK_RC_STYLE_GET_PRIVATE (new_style);
- new_priv->color_hashes = rc_priv->color_hashes;
- rc_priv->color_hashes = NULL;
- }
- else
- (*rc_style)->engine_specified = TRUE;
- }
- else
- {
- engine = gtk_theme_engine_get (scanner->value.v_string);
-
- token = g_scanner_get_next_token (scanner);
- if (token != G_TOKEN_LEFT_CURLY)
- return G_TOKEN_LEFT_CURLY;
-
- if (engine)
- {
- GtkRcStyleClass *new_class;
-
- rc_priv = GTK_RC_STYLE_GET_PRIVATE (*rc_style);
- new_style = gtk_theme_engine_create_rc_style (engine);
- g_type_module_unuse (G_TYPE_MODULE (engine));
-
- new_class = GTK_RC_STYLE_GET_CLASS (new_style);
-
- new_class->merge (new_style, *rc_style);
-
- new_style->name = g_strdup ((*rc_style)->name);
-
- /* take over icon factories and color hashes
- * from the to-be-deleted style
- */
- new_style->icon_factories = (*rc_style)->icon_factories;
- (*rc_style)->icon_factories = NULL;
- new_priv = GTK_RC_STYLE_GET_PRIVATE (new_style);
- new_priv->color_hashes = rc_priv->color_hashes;
- rc_priv->color_hashes = NULL;
-
- if (new_class->parse)
- {
- parsed_curlies = TRUE;
- result = new_class->parse (new_style, context->settings, scanner);
-
- if (result != G_TOKEN_NONE)
- {
- /* copy icon factories and color hashes back
- */
- (*rc_style)->icon_factories = new_style->icon_factories;
- new_style->icon_factories = NULL;
- rc_priv->color_hashes = new_priv->color_hashes;
- new_priv->color_hashes = NULL;
-
- g_object_unref (new_style);
- new_style = NULL;
- }
- }
- }
- }
-
- if (!parsed_curlies)
- {
- /* Skip over remainder, looking for nested {}'s
- */
- guint count = 1;
-
- result = G_TOKEN_RIGHT_CURLY;
- while ((token = g_scanner_get_next_token (scanner)) != G_TOKEN_EOF)
- {
- if (token == G_TOKEN_LEFT_CURLY)
- count++;
- else if (token == G_TOKEN_RIGHT_CURLY)
- count--;
-
- if (count == 0)
- {
- result = G_TOKEN_NONE;
- break;
- }
- }
- }
-
- if (new_style)
- {
- new_style->engine_specified = TRUE;
-
- g_object_unref (*rc_style);
- *rc_style = new_style;
- }
-
- return result;
-}
-
-/**
- * gtk_rc_parse_state:
- * @scanner:
- * @state:
- *
- * Deprecated:3.0: Use #GtkCssProvider instead
- */
-guint
-gtk_rc_parse_state (GScanner *scanner,
- GtkStateType *state)
-{
- guint old_scope;
- guint token;
-
- g_return_val_if_fail (scanner != NULL, G_TOKEN_ERROR);
- g_return_val_if_fail (state != NULL, G_TOKEN_ERROR);
-
- /* we don't know where we got called from, so we reset the scope here.
- * if we bail out due to errors, we *don't* reset the scope, so the
- * error messaging code can make sense of our tokens.
- */
- old_scope = g_scanner_set_scope (scanner, 0);
-
- token = g_scanner_get_next_token (scanner);
- if (token != G_TOKEN_LEFT_BRACE)
- return G_TOKEN_LEFT_BRACE;
-
- token = g_scanner_get_next_token (scanner);
- switch (token)
- {
- case GTK_RC_TOKEN_ACTIVE:
- *state = GTK_STATE_ACTIVE;
- break;
- case GTK_RC_TOKEN_INSENSITIVE:
- *state = GTK_STATE_INSENSITIVE;
- break;
- case GTK_RC_TOKEN_NORMAL:
- *state = GTK_STATE_NORMAL;
- break;
- case GTK_RC_TOKEN_PRELIGHT:
- *state = GTK_STATE_PRELIGHT;
- break;
- case GTK_RC_TOKEN_SELECTED:
- *state = GTK_STATE_SELECTED;
- break;
- default:
- return /* G_TOKEN_SYMBOL */ GTK_RC_TOKEN_NORMAL;
- }
-
- token = g_scanner_get_next_token (scanner);
- if (token != G_TOKEN_RIGHT_BRACE)
- return G_TOKEN_RIGHT_BRACE;
-
- g_scanner_set_scope (scanner, old_scope);
-
- return G_TOKEN_NONE;
-}
-
-/**
- * gtk_rc_parse_priority:
- * @scanner:
- * @priority:
- *
- * Deprecated:3.0: Use #GtkCssProvider instead
- */
-guint
-gtk_rc_parse_priority (GScanner *scanner,
- GtkPathPriorityType *priority)
-{
- guint old_scope;
- guint token;
-
- g_return_val_if_fail (scanner != NULL, G_TOKEN_ERROR);
- g_return_val_if_fail (priority != NULL, G_TOKEN_ERROR);
-
- /* we don't know where we got called from, so we reset the scope here.
- * if we bail out due to errors, we *don't* reset the scope, so the
- * error messaging code can make sense of our tokens.
- */
- old_scope = g_scanner_set_scope (scanner, 0);
-
- token = g_scanner_get_next_token (scanner);
- if (token != ':')
- return ':';
-
- token = g_scanner_get_next_token (scanner);
- switch (token)
- {
- case GTK_RC_TOKEN_LOWEST:
- *priority = GTK_PATH_PRIO_LOWEST;
- break;
- case GTK_RC_TOKEN_GTK:
- *priority = GTK_PATH_PRIO_GTK;
- break;
- case GTK_RC_TOKEN_APPLICATION:
- *priority = GTK_PATH_PRIO_APPLICATION;
- break;
- case GTK_RC_TOKEN_THEME:
- *priority = GTK_PATH_PRIO_THEME;
- break;
- case GTK_RC_TOKEN_RC:
- *priority = GTK_PATH_PRIO_RC;
- break;
- case GTK_RC_TOKEN_HIGHEST:
- *priority = GTK_PATH_PRIO_HIGHEST;
- break;
- default:
- return /* G_TOKEN_SYMBOL */ GTK_RC_TOKEN_APPLICATION;
- }
-
- g_scanner_set_scope (scanner, old_scope);
-
- return G_TOKEN_NONE;
-}
-
-/**
- * gtk_rc_parse_color:
- * @scanner: a #GScanner
- * @color: a pointer to a #GdkColor structure in which to store the result
- *
- * Parses a color in the <link linkend="color=format">format</link> expected
- * in a RC file.
- *
- * Note that theme engines should use gtk_rc_parse_color_full() in
- * order to support symbolic colors.
- *
- * Returns: %G_TOKEN_NONE if parsing succeeded, otherwise the token
- * that was expected but not found
- *
- * Deprecated:3.0: Use #GtkCssProvider instead
- */
-guint
-gtk_rc_parse_color (GScanner *scanner,
- GdkColor *color)
-{
- return gtk_rc_parse_color_full (scanner, NULL, color);
-}
-
-/**
- * gtk_rc_parse_color_full:
- * @scanner: a #GScanner
- * @style: (allow-none): a #GtkRcStyle, or %NULL
- * @color: a pointer to a #GdkColor structure in which to store the result
- *
- * Parses a color in the <link linkend="color=format">format</link> expected
- * in a RC file. If @style is not %NULL, it will be consulted to resolve
- * references to symbolic colors.
- *
- * Returns: %G_TOKEN_NONE if parsing succeeded, otherwise the token
- * that was expected but not found
- *
- * Since: 2.12
- *
- * Deprecated:3.0: Use #GtkCssProvider instead
- */
-guint
-gtk_rc_parse_color_full (GScanner *scanner,
- GtkRcStyle *style,
- GdkColor *color)
-{
- guint token;
-
- g_return_val_if_fail (scanner != NULL, G_TOKEN_ERROR);
-
- /* we don't need to set our own scope here, because
- * we don't need own symbols
- */
-
- token = g_scanner_get_next_token (scanner);
- switch (token)
- {
- gint token_int;
- GdkColor c1, c2;
- gboolean negate;
- gdouble l;
-
- case G_TOKEN_LEFT_CURLY:
- token = g_scanner_get_next_token (scanner);
- if (token == G_TOKEN_INT)
- token_int = scanner->value.v_int;
- else if (token == G_TOKEN_FLOAT)
- token_int = scanner->value.v_float * 65535.0;
- else
- return G_TOKEN_FLOAT;
- color->red = CLAMP (token_int, 0, 65535);
-
- token = g_scanner_get_next_token (scanner);
- if (token != G_TOKEN_COMMA)
- return G_TOKEN_COMMA;
-
- token = g_scanner_get_next_token (scanner);
- if (token == G_TOKEN_INT)
- token_int = scanner->value.v_int;
- else if (token == G_TOKEN_FLOAT)
- token_int = scanner->value.v_float * 65535.0;
- else
- return G_TOKEN_FLOAT;
- color->green = CLAMP (token_int, 0, 65535);
-
- token = g_scanner_get_next_token (scanner);
- if (token != G_TOKEN_COMMA)
- return G_TOKEN_COMMA;
-
- token = g_scanner_get_next_token (scanner);
- if (token == G_TOKEN_INT)
- token_int = scanner->value.v_int;
- else if (token == G_TOKEN_FLOAT)
- token_int = scanner->value.v_float * 65535.0;
- else
- return G_TOKEN_FLOAT;
- color->blue = CLAMP (token_int, 0, 65535);
-
- token = g_scanner_get_next_token (scanner);
- if (token != G_TOKEN_RIGHT_CURLY)
- return G_TOKEN_RIGHT_CURLY;
- return G_TOKEN_NONE;
-
- case G_TOKEN_STRING:
- if (!gdk_color_parse (scanner->value.v_string, color))
- {
- g_scanner_warn (scanner, "Invalid color constant '%s'",
- scanner->value.v_string);
- return G_TOKEN_STRING;
- }
- return G_TOKEN_NONE;
-
- case '@':
- token = g_scanner_get_next_token (scanner);
- if (token != G_TOKEN_IDENTIFIER)
- return G_TOKEN_IDENTIFIER;
-
- if (!style || !lookup_color (style, scanner->value.v_identifier, color))
- {
- g_scanner_warn (scanner, "Invalid symbolic color '%s'",
- scanner->value.v_identifier);
- return G_TOKEN_IDENTIFIER;
- }
-
- return G_TOKEN_NONE;
-
- case G_TOKEN_IDENTIFIER:
- if (strcmp (scanner->value.v_identifier, "mix") == 0)
- {
- token = g_scanner_get_next_token (scanner);
- if (token != G_TOKEN_LEFT_PAREN)
- return G_TOKEN_LEFT_PAREN;
-
- negate = FALSE;
- if (g_scanner_peek_next_token (scanner) == '-')
- {
- g_scanner_get_next_token (scanner); /* eat sign */
- negate = TRUE;
- }
-
- token = g_scanner_get_next_token (scanner);
- if (token != G_TOKEN_FLOAT)
- return G_TOKEN_FLOAT;
-
- l = negate ? -scanner->value.v_float : scanner->value.v_float;
-
- token = g_scanner_get_next_token (scanner);
- if (token != G_TOKEN_COMMA)
- return G_TOKEN_COMMA;
-
- token = gtk_rc_parse_color_full (scanner, style, &c1);
- if (token != G_TOKEN_NONE)
- return token;
-
- token = g_scanner_get_next_token (scanner);
- if (token != G_TOKEN_COMMA)
- return G_TOKEN_COMMA;
-
- token = gtk_rc_parse_color_full (scanner, style, &c2);
- if (token != G_TOKEN_NONE)
- return token;
-
- token = g_scanner_get_next_token (scanner);
- if (token != G_TOKEN_RIGHT_PAREN)
- return G_TOKEN_RIGHT_PAREN;
-
- color->red = l * c1.red + (1.0 - l) * c2.red;
- color->green = l * c1.green + (1.0 - l) * c2.green;
- color->blue = l * c1.blue + (1.0 - l) * c2.blue;
-
- return G_TOKEN_NONE;
- }
- else if (strcmp (scanner->value.v_identifier, "shade") == 0)
- {
- token = g_scanner_get_next_token (scanner);
- if (token != G_TOKEN_LEFT_PAREN)
- return G_TOKEN_LEFT_PAREN;
-
- negate = FALSE;
- if (g_scanner_peek_next_token (scanner) == '-')
- {
- g_scanner_get_next_token (scanner); /* eat sign */
- negate = TRUE;
- }
-
- token = g_scanner_get_next_token (scanner);
- if (token != G_TOKEN_FLOAT)
- return G_TOKEN_FLOAT;
-
- l = negate ? -scanner->value.v_float : scanner->value.v_float;
-
- token = g_scanner_get_next_token (scanner);
- if (token != G_TOKEN_COMMA)
- return G_TOKEN_COMMA;
-
- token = gtk_rc_parse_color_full (scanner, style, &c1);
- if (token != G_TOKEN_NONE)
- return token;
-
- token = g_scanner_get_next_token (scanner);
- if (token != G_TOKEN_RIGHT_PAREN)
- return G_TOKEN_RIGHT_PAREN;
-
- _gtk_style_shade (&c1, color, l);
-
- return G_TOKEN_NONE;
- }
- else if (strcmp (scanner->value.v_identifier, "lighter") == 0 ||
- strcmp (scanner->value.v_identifier, "darker") == 0)
- {
- if (scanner->value.v_identifier[0] == 'l')
- l = 1.3;
- else
- l = 0.7;
-
- token = g_scanner_get_next_token (scanner);
- if (token != G_TOKEN_LEFT_PAREN)
- return G_TOKEN_LEFT_PAREN;
-
- token = gtk_rc_parse_color_full (scanner, style, &c1);
- if (token != G_TOKEN_NONE)
- return token;
-
- token = g_scanner_get_next_token (scanner);
- if (token != G_TOKEN_RIGHT_PAREN)
- return G_TOKEN_RIGHT_PAREN;
-
- _gtk_style_shade (&c1, color, l);
-
- return G_TOKEN_NONE;
- }
- else
- return G_TOKEN_IDENTIFIER;
-
- default:
- return G_TOKEN_STRING;
- }
-}
-
-static guint
-gtk_rc_parse_pixmap_path (GtkRcContext *context,
- GScanner *scanner)
-{
- guint token;
-
- token = g_scanner_get_next_token (scanner);
- if (token != GTK_RC_TOKEN_PIXMAP_PATH)
- return GTK_RC_TOKEN_PIXMAP_PATH;
-
- token = g_scanner_get_next_token (scanner);
- if (token != G_TOKEN_STRING)
- return G_TOKEN_STRING;
-
- gtk_rc_parse_pixmap_path_string (context, scanner, scanner->value.v_string);
-
- return G_TOKEN_NONE;
-}
-
-static void
-gtk_rc_parse_pixmap_path_string (GtkRcContext *context,
- GScanner *scanner,
- const gchar *pix_path)
-{
- g_strfreev (context->pixmap_path);
- context->pixmap_path = g_strsplit (pix_path, G_SEARCHPATH_SEPARATOR_S, -1);
-}
-
-static guint
-gtk_rc_parse_module_path (GScanner *scanner)
-{
- guint token;
-
- token = g_scanner_get_next_token (scanner);
- if (token != GTK_RC_TOKEN_MODULE_PATH)
- return GTK_RC_TOKEN_MODULE_PATH;
-
- token = g_scanner_get_next_token (scanner);
- if (token != G_TOKEN_STRING)
- return G_TOKEN_STRING;
-
- g_warning ("module_path directive is now ignored\n");
-
- return G_TOKEN_NONE;
-}
+ g_return_val_if_fail (scanner != NULL, G_TOKEN_ERROR);
+ g_return_val_if_fail (priority != NULL, G_TOKEN_ERROR);
-static guint
-gtk_rc_parse_im_module_file (GScanner *scanner)
-{
- guint token;
-
- token = g_scanner_get_next_token (scanner);
- if (token != GTK_RC_TOKEN_IM_MODULE_FILE)
- return GTK_RC_TOKEN_IM_MODULE_FILE;
+ /* we don't know where we got called from, so we reset the scope here.
+ * if we bail out due to errors, we *don't* reset the scope, so the
+ * error messaging code can make sense of our tokens.
+ */
+ old_scope = g_scanner_set_scope (scanner, 0);
token = g_scanner_get_next_token (scanner);
- if (token != G_TOKEN_STRING)
- return G_TOKEN_STRING;
-
- g_free (im_module_file);
-
- im_module_file = g_strdup (scanner->value.v_string);
-
- return G_TOKEN_NONE;
-}
-
-static guint
-gtk_rc_parse_path_pattern (GtkRcContext *context,
- GScanner *scanner)
-{
- guint token;
- GtkPathType path_type;
- gchar *pattern;
- gboolean is_binding;
- GtkPathPriorityType priority = context->default_priority;
+ if (token != ':')
+ return ':';
token = g_scanner_get_next_token (scanner);
switch (token)
{
- case GTK_RC_TOKEN_WIDGET:
- path_type = GTK_PATH_WIDGET;
+ case GTK_RC_TOKEN_LOWEST:
+ *priority = GTK_PATH_PRIO_LOWEST;
+ break;
+ case GTK_RC_TOKEN_GTK:
+ *priority = GTK_PATH_PRIO_GTK;
+ break;
+ case GTK_RC_TOKEN_APPLICATION:
+ *priority = GTK_PATH_PRIO_APPLICATION;
+ break;
+ case GTK_RC_TOKEN_THEME:
+ *priority = GTK_PATH_PRIO_THEME;
break;
- case GTK_RC_TOKEN_WIDGET_CLASS:
- path_type = GTK_PATH_WIDGET_CLASS;
+ case GTK_RC_TOKEN_RC:
+ *priority = GTK_PATH_PRIO_RC;
break;
- case GTK_RC_TOKEN_CLASS:
- path_type = GTK_PATH_CLASS;
+ case GTK_RC_TOKEN_HIGHEST:
+ *priority = GTK_PATH_PRIO_HIGHEST;
break;
default:
- return GTK_RC_TOKEN_WIDGET_CLASS;
- }
-
- token = g_scanner_get_next_token (scanner);
- if (token != G_TOKEN_STRING)
- return G_TOKEN_STRING;
-
- pattern = g_strdup (scanner->value.v_string);
-
- token = g_scanner_get_next_token (scanner);
- if (token == GTK_RC_TOKEN_STYLE)
- is_binding = FALSE;
- else if (token == GTK_RC_TOKEN_BINDING)
- is_binding = TRUE;
- else
- {
- g_free (pattern);
- return GTK_RC_TOKEN_STYLE;
- }
-
- if (g_scanner_peek_next_token (scanner) == ':')
- {
- token = gtk_rc_parse_priority (scanner, &priority);
- if (token != G_TOKEN_NONE)
- {
- g_free (pattern);
- return token;
- }
+ return /* G_TOKEN_SYMBOL */ GTK_RC_TOKEN_APPLICATION;
}
- token = g_scanner_get_next_token (scanner);
- if (token != G_TOKEN_STRING)
- {
- g_free (pattern);
- return G_TOKEN_STRING;
- }
-
- if (is_binding)
- {
- GtkBindingSet *binding;
-
- binding = gtk_binding_set_find (scanner->value.v_string);
- if (!binding)
- {
- g_free (pattern);
- return G_TOKEN_STRING;
- }
- gtk_binding_set_add_path (binding, path_type, pattern, priority);
- }
- else
- {
- GtkRcStyle *rc_style;
- GtkRcSet *rc_set;
-
- rc_style = gtk_rc_style_find (context, scanner->value.v_string);
-
- if (!rc_style)
- {
- g_free (pattern);
- return G_TOKEN_STRING;
- }
-
- rc_set = g_new (GtkRcSet, 1);
- rc_set->type = path_type;
-
- if (path_type == GTK_PATH_WIDGET_CLASS)
- {
- rc_set->pspec = NULL;
- rc_set->path = _gtk_rc_parse_widget_class_path (pattern);
- }
- else
- {
- rc_set->pspec = g_pattern_spec_new (pattern);
- rc_set->path = NULL;
- }
-
- rc_set->rc_style = rc_style;
- rc_set->priority = priority;
-
- if (path_type == GTK_PATH_WIDGET)
- context->rc_sets_widget = g_slist_prepend (context->rc_sets_widget, rc_set);
- else if (path_type == GTK_PATH_WIDGET_CLASS)
- context->rc_sets_widget_class = g_slist_prepend (context->rc_sets_widget_class, rc_set);
- else
- context->rc_sets_class = g_slist_prepend (context->rc_sets_class, rc_set);
- }
+ g_scanner_set_scope (scanner, old_scope);
- g_free (pattern);
return G_TOKEN_NONE;
}
-static guint
-gtk_rc_parse_hash_key (GScanner *scanner,
- gchar **hash_key)
+/**
+ * gtk_rc_parse_color:
+ * @scanner: a #GScanner
+ * @color: a pointer to a #GdkColor structure in which to store the result
+ *
+ * Parses a color in the <link linkend="color=format">format</link> expected
+ * in a RC file.
+ *
+ * Note that theme engines should use gtk_rc_parse_color_full() in
+ * order to support symbolic colors.
+ *
+ * Returns: %G_TOKEN_NONE if parsing succeeded, otherwise the token
+ * that was expected but not found
+ *
+ * Deprecated:3.0: Use #GtkCssProvider instead
+ */
+guint
+gtk_rc_parse_color (GScanner *scanner,
+ GdkColor *color)
{
- guint token;
-
- token = g_scanner_get_next_token (scanner);
- if (token != G_TOKEN_LEFT_BRACE)
- return G_TOKEN_LEFT_BRACE;
-
- token = g_scanner_get_next_token (scanner);
-
- if (token != G_TOKEN_STRING)
- return G_TOKEN_STRING;
-
- *hash_key = g_strdup (scanner->value.v_string);
-
- token = g_scanner_get_next_token (scanner);
- if (token != G_TOKEN_RIGHT_BRACE)
- {
- g_free (*hash_key);
- return G_TOKEN_RIGHT_BRACE;
- }
-
- return G_TOKEN_NONE;
+ return gtk_rc_parse_color_full (scanner, NULL, color);
}
-static guint
-gtk_rc_parse_icon_source (GtkRcContext *context,
- GScanner *scanner,
- GtkIconSet *icon_set,
- gboolean *icon_set_valid)
-{
- guint token;
- gchar *full_filename;
- GtkIconSource *source = NULL;
-
- token = g_scanner_get_next_token (scanner);
- if (token != G_TOKEN_LEFT_CURLY)
- return G_TOKEN_LEFT_CURLY;
-
- token = g_scanner_get_next_token (scanner);
-
- if (token != G_TOKEN_STRING && token != '@')
- return G_TOKEN_STRING;
-
- if (token == G_TOKEN_STRING)
- {
- /* Filename */
-
- source = gtk_icon_source_new ();
- full_filename = gtk_rc_find_pixmap_in_path (context->settings, scanner, scanner->value.v_string);
- if (full_filename)
- {
- gtk_icon_source_set_filename (source, full_filename);
- g_free (full_filename);
- }
- }
- else
- {
- /* Icon name */
-
- token = g_scanner_get_next_token (scanner);
-
- if (token != G_TOKEN_STRING)
- return G_TOKEN_STRING;
+/**
+ * gtk_rc_parse_color_full:
+ * @scanner: a #GScanner
+ * @style: (allow-none): a #GtkRcStyle, or %NULL
+ * @color: a pointer to a #GdkColor structure in which to store the result
+ *
+ * Parses a color in the <link linkend="color=format">format</link> expected
+ * in a RC file. If @style is not %NULL, it will be consulted to resolve
+ * references to symbolic colors.
+ *
+ * Returns: %G_TOKEN_NONE if parsing succeeded, otherwise the token
+ * that was expected but not found
+ *
+ * Since: 2.12
+ *
+ * Deprecated:3.0: Use #GtkCssProvider instead
+ */
+guint
+gtk_rc_parse_color_full (GScanner *scanner,
+ GtkRcStyle *style,
+ GdkColor *color)
+{
+ guint token;
- source = gtk_icon_source_new ();
- gtk_icon_source_set_icon_name (source, scanner->value.v_string);
- }
+ g_return_val_if_fail (scanner != NULL, G_TOKEN_ERROR);
- /* We continue parsing even if we didn't find the pixmap so that rest of the
- * file is read, even if the syntax is bad. However we don't validate the
- * icon_set so the caller can choose not to install it.
+ /* we don't need to set our own scope here, because
+ * we don't need own symbols
*/
- token = g_scanner_get_next_token (scanner);
-
- if (token == G_TOKEN_RIGHT_CURLY)
- goto done;
- else if (token != G_TOKEN_COMMA)
- {
- gtk_icon_source_free (source);
- return G_TOKEN_COMMA;
- }
-
- /* Get the direction */
token = g_scanner_get_next_token (scanner);
-
switch (token)
{
- case GTK_RC_TOKEN_RTL:
- gtk_icon_source_set_direction_wildcarded (source, FALSE);
- gtk_icon_source_set_direction (source, GTK_TEXT_DIR_RTL);
- break;
+ gint token_int;
+ GdkColor c1, c2;
+ gboolean negate;
+ gdouble l;
- case GTK_RC_TOKEN_LTR:
- gtk_icon_source_set_direction_wildcarded (source, FALSE);
- gtk_icon_source_set_direction (source, GTK_TEXT_DIR_LTR);
- break;
+ case G_TOKEN_LEFT_CURLY:
+ token = g_scanner_get_next_token (scanner);
+ if (token == G_TOKEN_INT)
+ token_int = scanner->value.v_int;
+ else if (token == G_TOKEN_FLOAT)
+ token_int = scanner->value.v_float * 65535.0;
+ else
+ return G_TOKEN_FLOAT;
+ color->red = CLAMP (token_int, 0, 65535);
- case '*':
- break;
+ token = g_scanner_get_next_token (scanner);
+ if (token != G_TOKEN_COMMA)
+ return G_TOKEN_COMMA;
- default:
- gtk_icon_source_free (source);
- return GTK_RC_TOKEN_RTL;
- break;
- }
+ token = g_scanner_get_next_token (scanner);
+ if (token == G_TOKEN_INT)
+ token_int = scanner->value.v_int;
+ else if (token == G_TOKEN_FLOAT)
+ token_int = scanner->value.v_float * 65535.0;
+ else
+ return G_TOKEN_FLOAT;
+ color->green = CLAMP (token_int, 0, 65535);
+
+ token = g_scanner_get_next_token (scanner);
+ if (token != G_TOKEN_COMMA)
+ return G_TOKEN_COMMA;
+
+ token = g_scanner_get_next_token (scanner);
+ if (token == G_TOKEN_INT)
+ token_int = scanner->value.v_int;
+ else if (token == G_TOKEN_FLOAT)
+ token_int = scanner->value.v_float * 65535.0;
+ else
+ return G_TOKEN_FLOAT;
+ color->blue = CLAMP (token_int, 0, 65535);
+
+ token = g_scanner_get_next_token (scanner);
+ if (token != G_TOKEN_RIGHT_CURLY)
+ return G_TOKEN_RIGHT_CURLY;
+ return G_TOKEN_NONE;
+
+ case G_TOKEN_STRING:
+ if (!gdk_color_parse (scanner->value.v_string, color))
+ {
+ g_scanner_warn (scanner, "Invalid color constant '%s'",
+ scanner->value.v_string);
+ return G_TOKEN_STRING;
+ }
+ return G_TOKEN_NONE;
- token = g_scanner_get_next_token (scanner);
+ case '@':
+ token = g_scanner_get_next_token (scanner);
+ if (token != G_TOKEN_IDENTIFIER)
+ return G_TOKEN_IDENTIFIER;
- if (token == G_TOKEN_RIGHT_CURLY)
- goto done;
- else if (token != G_TOKEN_COMMA)
- {
- gtk_icon_source_free (source);
- return G_TOKEN_COMMA;
- }
+ if (!style || !lookup_color (style, scanner->value.v_identifier, color))
+ {
+ g_scanner_warn (scanner, "Invalid symbolic color '%s'",
+ scanner->value.v_identifier);
+ return G_TOKEN_IDENTIFIER;
+ }
- /* Get the state */
-
- token = g_scanner_get_next_token (scanner);
-
- switch (token)
- {
- case GTK_RC_TOKEN_NORMAL:
- gtk_icon_source_set_state_wildcarded (source, FALSE);
- gtk_icon_source_set_state (source, GTK_STATE_NORMAL);
- break;
+ return G_TOKEN_NONE;
- case GTK_RC_TOKEN_PRELIGHT:
- gtk_icon_source_set_state_wildcarded (source, FALSE);
- gtk_icon_source_set_state (source, GTK_STATE_PRELIGHT);
- break;
-
+ case G_TOKEN_IDENTIFIER:
+ if (strcmp (scanner->value.v_identifier, "mix") == 0)
+ {
+ token = g_scanner_get_next_token (scanner);
+ if (token != G_TOKEN_LEFT_PAREN)
+ return G_TOKEN_LEFT_PAREN;
- case GTK_RC_TOKEN_INSENSITIVE:
- gtk_icon_source_set_state_wildcarded (source, FALSE);
- gtk_icon_source_set_state (source, GTK_STATE_INSENSITIVE);
- break;
+ negate = FALSE;
+ if (g_scanner_peek_next_token (scanner) == '-')
+ {
+ g_scanner_get_next_token (scanner); /* eat sign */
+ negate = TRUE;
+ }
- case GTK_RC_TOKEN_ACTIVE:
- gtk_icon_source_set_state_wildcarded (source, FALSE);
- gtk_icon_source_set_state (source, GTK_STATE_ACTIVE);
- break;
+ token = g_scanner_get_next_token (scanner);
+ if (token != G_TOKEN_FLOAT)
+ return G_TOKEN_FLOAT;
- case GTK_RC_TOKEN_SELECTED:
- gtk_icon_source_set_state_wildcarded (source, FALSE);
- gtk_icon_source_set_state (source, GTK_STATE_SELECTED);
- break;
+ l = negate ? -scanner->value.v_float : scanner->value.v_float;
- case '*':
- break;
-
- default:
- gtk_icon_source_free (source);
- return GTK_RC_TOKEN_PRELIGHT;
- break;
- }
+ token = g_scanner_get_next_token (scanner);
+ if (token != G_TOKEN_COMMA)
+ return G_TOKEN_COMMA;
- token = g_scanner_get_next_token (scanner);
+ token = gtk_rc_parse_color_full (scanner, style, &c1);
+ if (token != G_TOKEN_NONE)
+ return token;
- if (token == G_TOKEN_RIGHT_CURLY)
- goto done;
- else if (token != G_TOKEN_COMMA)
- {
- gtk_icon_source_free (source);
- return G_TOKEN_COMMA;
- }
-
- /* Get the size */
-
- token = g_scanner_get_next_token (scanner);
+ token = g_scanner_get_next_token (scanner);
+ if (token != G_TOKEN_COMMA)
+ return G_TOKEN_COMMA;
- if (token != '*')
- {
- GtkIconSize size;
-
- if (token != G_TOKEN_STRING)
- {
- gtk_icon_source_free (source);
- return G_TOKEN_STRING;
- }
+ token = gtk_rc_parse_color_full (scanner, style, &c2);
+ if (token != G_TOKEN_NONE)
+ return token;
+
+ token = g_scanner_get_next_token (scanner);
+ if (token != G_TOKEN_RIGHT_PAREN)
+ return G_TOKEN_RIGHT_PAREN;
- size = gtk_icon_size_from_name (scanner->value.v_string);
+ color->red = l * c1.red + (1.0 - l) * c2.red;
+ color->green = l * c1.green + (1.0 - l) * c2.green;
+ color->blue = l * c1.blue + (1.0 - l) * c2.blue;
- if (size != GTK_ICON_SIZE_INVALID)
+ return G_TOKEN_NONE;
+ }
+ else if (strcmp (scanner->value.v_identifier, "shade") == 0)
{
- gtk_icon_source_set_size_wildcarded (source, FALSE);
- gtk_icon_source_set_size (source, size);
- }
- }
+ token = g_scanner_get_next_token (scanner);
+ if (token != G_TOKEN_LEFT_PAREN)
+ return G_TOKEN_LEFT_PAREN;
- /* Check the close brace */
-
- token = g_scanner_get_next_token (scanner);
- if (token != G_TOKEN_RIGHT_CURLY)
- {
- gtk_icon_source_free (source);
- return G_TOKEN_RIGHT_CURLY;
- }
+ negate = FALSE;
+ if (g_scanner_peek_next_token (scanner) == '-')
+ {
+ g_scanner_get_next_token (scanner); /* eat sign */
+ negate = TRUE;
+ }
- done:
- if (gtk_icon_source_get_filename (source) ||
- gtk_icon_source_get_icon_name (source))
- {
- gtk_icon_set_add_source (icon_set, source);
- *icon_set_valid = TRUE;
- }
- gtk_icon_source_free (source);
-
- return G_TOKEN_NONE;
-}
+ token = g_scanner_get_next_token (scanner);
+ if (token != G_TOKEN_FLOAT)
+ return G_TOKEN_FLOAT;
-static guint
-gtk_rc_parse_stock (GtkRcContext *context,
- GScanner *scanner,
- GtkRcStyle *rc_style,
- GtkIconFactory *factory)
-{
- GtkIconSet *icon_set = NULL;
- gboolean icon_set_valid = FALSE;
- gchar *stock_id = NULL;
- guint token;
-
- token = g_scanner_get_next_token (scanner);
- if (token != GTK_RC_TOKEN_STOCK)
- return GTK_RC_TOKEN_STOCK;
-
- token = gtk_rc_parse_hash_key (scanner, &stock_id);
- if (token != G_TOKEN_NONE)
- return token;
-
- token = g_scanner_get_next_token (scanner);
- if (token != G_TOKEN_EQUAL_SIGN)
- {
- g_free (stock_id);
- return G_TOKEN_EQUAL_SIGN;
- }
+ l = negate ? -scanner->value.v_float : scanner->value.v_float;
- token = g_scanner_get_next_token (scanner);
- if (token != G_TOKEN_LEFT_CURLY)
- {
- g_free (stock_id);
- return G_TOKEN_LEFT_CURLY;
- }
+ token = g_scanner_get_next_token (scanner);
+ if (token != G_TOKEN_COMMA)
+ return G_TOKEN_COMMA;
- token = g_scanner_peek_next_token (scanner);
- while (token != G_TOKEN_RIGHT_CURLY)
- {
- if (icon_set == NULL)
- icon_set = gtk_icon_set_new ();
-
- token = gtk_rc_parse_icon_source (context,
- scanner, icon_set, &icon_set_valid);
- if (token != G_TOKEN_NONE)
- {
- g_free (stock_id);
- gtk_icon_set_unref (icon_set);
- return token;
- }
+ token = gtk_rc_parse_color_full (scanner, style, &c1);
+ if (token != G_TOKEN_NONE)
+ return token;
- token = g_scanner_get_next_token (scanner);
-
- if (token != G_TOKEN_COMMA &&
- token != G_TOKEN_RIGHT_CURLY)
- {
- g_free (stock_id);
- gtk_icon_set_unref (icon_set);
- return G_TOKEN_RIGHT_CURLY;
- }
- }
+ token = g_scanner_get_next_token (scanner);
+ if (token != G_TOKEN_RIGHT_PAREN)
+ return G_TOKEN_RIGHT_PAREN;
- if (icon_set)
- {
- if (icon_set_valid)
- gtk_icon_factory_add (factory,
- stock_id,
- icon_set);
+ _gtk_style_shade (&c1, color, l);
- gtk_icon_set_unref (icon_set);
- }
-
- g_free (stock_id);
+ return G_TOKEN_NONE;
+ }
+ else if (strcmp (scanner->value.v_identifier, "lighter") == 0 ||
+ strcmp (scanner->value.v_identifier, "darker") == 0)
+ {
+ if (scanner->value.v_identifier[0] == 'l')
+ l = 1.3;
+ else
+ l = 0.7;
- return G_TOKEN_NONE;
-}
+ token = g_scanner_get_next_token (scanner);
+ if (token != G_TOKEN_LEFT_PAREN)
+ return G_TOKEN_LEFT_PAREN;
-static guint
-gtk_rc_parse_logical_color (GScanner *scanner,
- GtkRcStyle *rc_style,
- GHashTable *hash)
-{
- gchar *color_id = NULL;
- guint token;
- GdkColor color;
+ token = gtk_rc_parse_color_full (scanner, style, &c1);
+ if (token != G_TOKEN_NONE)
+ return token;
- token = g_scanner_get_next_token (scanner);
- if (token != GTK_RC_TOKEN_COLOR)
- return GTK_RC_TOKEN_COLOR;
+ token = g_scanner_get_next_token (scanner);
+ if (token != G_TOKEN_RIGHT_PAREN)
+ return G_TOKEN_RIGHT_PAREN;
- token = gtk_rc_parse_hash_key (scanner, &color_id);
- if (token != G_TOKEN_NONE)
- return token;
+ _gtk_style_shade (&c1, color, l);
- token = g_scanner_get_next_token (scanner);
- if (token != G_TOKEN_EQUAL_SIGN)
- {
- g_free (color_id);
- return G_TOKEN_EQUAL_SIGN;
- }
+ return G_TOKEN_NONE;
+ }
+ else
+ return G_TOKEN_IDENTIFIER;
- token = gtk_rc_parse_color_full (scanner, rc_style, &color);
- if (token != G_TOKEN_NONE)
- {
- g_free (color_id);
- return token;
+ default:
+ return G_TOKEN_STRING;
}
-
- /* Because the hash is created with destroy functions,
- * g_hash_table_insert will free any old values for us,
- * if a mapping with the specified key already exists.
- */
- g_hash_table_insert (hash, color_id, gdk_color_copy (&color));
-
- return G_TOKEN_NONE;
}
-
GSList *
_gtk_rc_parse_widget_class_path (const gchar *pattern)
{